package com.ball.common.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.*;
import lombok.extern.slf4j.Slf4j;

import java.io.InputStream;
import java.util.List;


@Slf4j
public class OssUtils implements IFileStorage {

    private final OSS ossClient;
    private final String bucketName;
    private final String endpoint;

    public OssUtils(OSS aliOssClient, String bucketName ,String endpoint)  {
        this.ossClient = aliOssClient;
        this.bucketName = bucketName;
        this.endpoint = endpoint;
    }

    /**
     * 上传文件到OSS（Amazon S3兼容接口）。
     *
     * @param key 上传文件在OSS中的存储路径和文件名。
     * @param inputStream 文件的内容流。
     * @param contentLength 文件的内容长度。
     * @return 上传成功后返回的请求ID。
     * @throws RuntimeException 如果上传失败。
     */
    @Override
    public String uploadFile(String key, InputStream inputStream, long contentLength) {
        // 1. 数据校验
        AssertUtils.isNotBlank(bucketName, "桶名字不能为null");
        AssertUtils.isNotBlank(key, "文件key不能为空");
        AssertUtils.isNotNull(inputStream);
        try {
            // 2. 处理文件元数据
            ObjectMetadata objectMeta = new ObjectMetadata();
            objectMeta.setContentLength(contentLength);
            // 3. 创建上传请求
            PutObjectRequest request = new PutObjectRequest(bucketName, key, inputStream, objectMeta);
            // 4. 执行上传操作
            PutObjectResult result = ossClient.putObject(request);
            // 5. 处理上传结果
            ResponseMessage response = result.getResponse();
            if (!response.isSuccessful()) {
                log.info("上传文件[{}]失败, 原因：{}", key, response.getErrorResponseAsString());
                throw new RuntimeException("上传文件失败!");
            }
            return "https://" + bucketName + "." + endpoint+"/" + key;
        } catch (Exception e) {
            log.error("上传文件[{}]失败 ", key, e);
            throw new RuntimeException("上传文件失败!", e);
        }
    }








    @Override
    public String uploadFile(String key, InputStream inputStream ) {
        // 1.数据校验
        AssertUtils.isNotBlank(bucketName, "桶名字不能为null");
        AssertUtils.isNotBlank(key, "文件key不能为空");
        AssertUtils.isNotNull(inputStream);
        try {
            // 3.请求参数
            PutObjectRequest request = new PutObjectRequest(bucketName, key, inputStream);
            // 4.上传
            PutObjectResult result = ossClient.putObject(request);
            if (result == null) {
                log.info("上传文件[{}]失败", key);
                throw new RuntimeException("上传文件失败!");
            }
            return  "https://" + bucketName + "." + endpoint+"/" + key;
        } catch (Exception e) {
            log.error("上传文件[{}]失败 ", key, e);
            throw new RuntimeException("上传文件失败!", e);
        }
    }




    @Override
    public InputStream downloadFile(String key) {
        // 1.数据校验

        AssertUtils.isNotBlank(bucketName, "桶名字不能为null");
        AssertUtils.isNotBlank(key, "文件key不能为空");
        try {
            GetObjectRequest request = new GetObjectRequest(bucketName, key);
            return ossClient.getObject(request).getObjectContent();
        } catch (Exception e) {
            log.error("下载文件[{}]时发生异常：", key, e);
            throw new RuntimeException("文件下载异常。", e);
        }
    }

    @Override
    public void deleteFile(String key) {
        // 1.数据校验
        // 1.数据校验
        AssertUtils.isNotBlank(bucketName, "桶名字不能为null");
        AssertUtils.isNotBlank(key, "文件key不能为空");
        try {
            // 2.删除
            ossClient.deleteObject(bucketName, key);
        } catch (Exception e) {
            log.error("删除文件[{}]时发生异常：", key, e);
            throw new RuntimeException("删除异常。", e);
        }
    }

    @Override
    public void deleteFiles(List<String> keys) {
        // 1.数据校验
        if(CollUtils.isEmpty(keys)){
            return;
        }
        AssertUtils.isNotBlank(bucketName, "桶的名字不能为空");
        if(keys.size() > 1000){
            throw new RuntimeException("文件的key不能超过1000");
        }
        // 2.准备request
        DeleteObjectsRequest request = new DeleteObjectsRequest(bucketName).withKeys(keys);
        try {
            // 3.删除
            ossClient.deleteObjects(request);
        } catch (Exception e) {
            log.error("批量删除文件[{}]时发生异常：", keys, e);
            throw new RuntimeException("删除异常。", e);
        }
    }
}
